package com.wz.boot.function.weather;

import com.alibaba.fastjson.JSONObject;
import com.wz.boot.annotation.Function;
import com.wz.boot.annotation.Handle;
import com.wz.boot.constant.Constant;
import com.wz.boot.dao.weather.WeatherLogDao;
import com.wz.boot.dao.weather.WeatherSettingDao;
import com.wz.boot.dao.weather.WeatherSubscriptionDao;
import com.wz.boot.pojo.weather.WeatherLog;
import com.wz.boot.pojo.weather.WeatherSetting;
import com.wz.boot.pojo.weather.WeatherSubscription;
import com.wz.boot.utils.HttpUtils;
import com.wz.boot.utils.Uid;
import love.forte.simbot.api.message.events.PrivateMsg;
import love.forte.simbot.api.sender.MsgSender;
import love.forte.simbot.api.sender.Sender;
import love.forte.simbot.bot.BotManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Function(
        priority = 4,
        name = "天气订阅",
        describe = "订阅天气,我推给你",
        touch = "天气订阅",
        claName = "Weather"
)
@Component
@EnableScheduling
public class Weather {

    private static Logger logger = LoggerFactory.getLogger(Weather.class);

    @Autowired
    WeatherLogDao weatherLogDao;
    @Autowired
    WeatherSettingDao weatherSettingDao;
    @Autowired
    WeatherSubscriptionDao weatherSubscriptionDao;
    @Autowired
    Constant constant;


    MsgSender sender;
    @Autowired(required = false)
    public void setSender(BotManager botManager){
        sender = botManager.getDefaultBot().getSender();
    }

    Map<Long,String> methodPositionMap = new HashMap<>();

    @Handle(defaultHandle = true)
    public void weatherSearch(PrivateMsg privateMsg, Sender sender) throws InvocationTargetException, IllegalAccessException {
        Long qqAccount = privateMsg.getAccountInfo().getAccountCodeNumber();
        String methodPosition = methodPositionMap.get(qqAccount);
        //对方法进行拦截,执行相应方法
        if(methodPosition != null && !methodPosition.isEmpty()){
            Method[] methods = this.getClass().getMethods();
            for (Method method : methods) {
                String methodName = method.getName();
                if(methodPosition.equalsIgnoreCase(methodName)){
                    method.invoke(this,privateMsg,sender);
                    return;
                }
            }
            logger.error("天气预定中,未找到指定的方法");
        }

        //回复指令
        sender.sendPrivateMsg(privateMsg,"请输入以下指令：\n[我的订阅][我要订阅天气][现在的天气][删除订阅][删除所有订阅]");


//        String msg = privateMsg.getMsgContent().getMsg();
//        logger.info("当前查询的天气位置信息: {}", msg);
//        //根据msg去中国气象台网站爬取天气
//        //todo
//        String weatherMsg = "";
//        sender.sendPrivateMsg(privateMsg, "您当前位置的天气：" + weatherMsg);

    }

    @Handle(touch = "我的订阅")
    public void changePosition(PrivateMsg privateMsg, Sender sender){
        String qqAccount = privateMsg.getAccountInfo().getAccountCode();
        List<WeatherSubscription> weatherSubscriptionList = weatherSubscriptionDao.selectWeatherSubscriptionByQqAccount(qqAccount);
        StringBuilder subscriptionText = new StringBuilder("以下是您订阅的天气详情:\n\n");
        for (WeatherSubscription weatherSubscription : weatherSubscriptionList) {
            String placeName = weatherSubscription.getPlaceName();
            String timeNode = weatherSubscription.getTimeNode();

            subscriptionText
                    .append("[地区]:" + placeName)
                    .append("[时间]:" + timeNode+" （点)" + "\n");

        }
        sender.sendPrivateMsg(privateMsg,subscriptionText.toString());
    }

    @Handle(touch = "我要订阅天气")
    public void subscribeWeather(PrivateMsg privateMsg, Sender sender){
        Long qqAccount = privateMsg.getAccountInfo().getAccountCodeNumber();
        String methodPosition = methodPositionMap.get(qqAccount);
        if(methodPosition == null || methodPosition.isEmpty()){
            sender.sendPrivateMsg(privateMsg,"请输入您想订阅的天气;\n\n格式:[地区-时间点];\n\n例如：北京市-6");
            //当前可订阅的天气地点
            StringBuilder weatherSettingText = new StringBuilder("以下是可订阅的地方：\n");
            List<WeatherSetting> weatherSettingList = weatherSettingDao.selectAllWeatherSetting();
            for (WeatherSetting weatherSetting : weatherSettingList) {
                weatherSettingText.append(weatherSetting.getPlaceName()+"\n");
            }
            sender.sendPrivateMsg(privateMsg,weatherSettingText.toString());
            methodPositionMap.put(qqAccount,"subscribeWeather");
        }else {
            String rMsg = privateMsg.getMsgContent().getMsg();
            String[] split = rMsg.split("-");
            if(split.length == 2){
                String placeName = split[0];
                String timeNode = split[1];
                WeatherSetting weatherSetting = weatherSettingDao.selectAllWeatherByPlaceName(placeName);
                Boolean aBoolean = weatherSubscriptionDao.addWeatherSubscription(Uid.randomUid(), weatherSetting.getUid(), qqAccount+"", placeName, timeNode);
                if(aBoolean){
                    sender.sendPrivateMsg(privateMsg,"订阅成功：" + rMsg);
                }else{
                    sender.sendPrivateMsg(privateMsg,"该订阅已存在或未订阅成功：" + rMsg);
                }
            }else {
                sender.sendPrivateMsg(privateMsg,"格式输入错误");
            }
            methodPositionMap.put(qqAccount,"");
        }
    }
    //todo
    @Handle(touch = "现在的天气")
    public void nowWeather(PrivateMsg privateMsg, Sender sender){
        List<WeatherSubscription> weatherSubscriptionList = weatherSubscriptionDao.selectWeatherSubscriptionByQqAccount(privateMsg.getAccountInfo().getAccountCode());
        for (WeatherSubscription weatherSubscription : weatherSubscriptionList) {
            String qqAccount = weatherSubscription.getQqAccount();
            String placeName = weatherSubscription.getPlaceName();
            WeatherLog weatherLog = weatherLogDao.selectWeatherLogByPlaceName(placeName);
            if(weatherLog != null ){
                String info = parseToInfo(weatherLog);
                sender.sendPrivateMsg(qqAccount,info);
            }
        }
    }
    @Handle(touch = "删除订阅")
    public void removeSubscription(PrivateMsg privateMsg, Sender sender){
        Long qqAccount = privateMsg.getAccountInfo().getAccountCodeNumber();
        String methodPosition = methodPositionMap.get(qqAccount);
        if(methodPosition == null || methodPosition.isEmpty()){
            sender.sendPrivateMsg(privateMsg,"请输入您想删除的天气订阅;\n\n格式:[地区-时间点];\n\n例如：北京市-6");
            methodPositionMap.put(qqAccount,"removeSubscription");
        }else {
            String rMsg = privateMsg.getMsgContent().getMsg();
            String[] split = rMsg.split("-");
            if(split.length == 2){
                String placeName = split[0];
                String timeNode = split[1];
                Boolean aBoolean = weatherSubscriptionDao.deleteWeatherSubscription(qqAccount+"", placeName, timeNode);
                if(aBoolean){
                    sender.sendPrivateMsg(privateMsg,"删除成功：" + rMsg);
                }else{
                    sender.sendPrivateMsg(privateMsg,"该预定已被删除或不存在：" + rMsg);
                }
            }else {
                sender.sendPrivateMsg(privateMsg,"格式输入错误");
            }
            methodPositionMap.put(qqAccount,"");
        }
    }
    @Handle(touch = "删除所有订阅")
    public void removeAllSubscription(PrivateMsg privateMsg, Sender sender){
        String qqAccount = privateMsg.getAccountInfo().getAccountCode();
        weatherSubscriptionDao.deleteWeatherSubscriptionByQqAccount(qqAccount);

        sender.sendPrivateMsg(privateMsg,"您已删除所有天气订阅");
    }

    /**
     * 定时器，分为三个时间节点 早上六点
     * 6：00
     * 12:00
     * 18:00
     */
    @Scheduled(cron = "0 0 6 * * ?")
//    @Scheduled(cron = "*/20 * * * * ?")
    public void timing6(){
        //开始得到天气，存到数据库中
        String baseUrl = "http://api.tianapi.com/txapi/tianqi/index";
        List<WeatherSetting> weatherSettingList = weatherSettingDao.selectAllWeatherSetting();
        for (WeatherSetting weatherSetting : weatherSettingList) {
            String placeName = weatherSetting.getPlaceName();
            crawling(baseUrl,placeName);
        }


        //开始推送
        List<WeatherSubscription> weatherSubscriptionList = weatherSubscriptionDao.selectWeatherSubscriptionByTimeNode6();
        for (WeatherSubscription weatherSubscription : weatherSubscriptionList) {
            String qqAccount = weatherSubscription.getQqAccount();
            String placeName = weatherSubscription.getPlaceName();
            WeatherLog weatherLog = weatherLogDao.selectWeatherLogByPlaceName(placeName);
            String info = parseToInfo(weatherLog);
            sender.SENDER.sendPrivateMsg(qqAccount,info);

        }
    }



    @Scheduled(cron = "0 0 12 * * ?")
//    @Scheduled(cron = "*/10 * * * * ?")
    public void timing12(){
        //开始推送
        //开始推送
        List<WeatherSubscription> weatherSubscriptionList = weatherSubscriptionDao.selectWeatherSubscriptionByTimeNode12();
        for (WeatherSubscription weatherSubscription : weatherSubscriptionList) {
            String qqAccount = weatherSubscription.getQqAccount();
            String placeName = weatherSubscription.getPlaceName();
            WeatherLog weatherLog = weatherLogDao.selectWeatherLogByPlaceName(placeName);
            String info = parseToInfo(weatherLog);
            sender.SENDER.sendPrivateMsg(qqAccount,info);

        }

    }
    @Scheduled(cron = "0 0 18 * * ?")
    public void timing18(){
        //开始推送
        List<WeatherSubscription> weatherSubscriptionList = weatherSubscriptionDao.selectWeatherSubscriptionByTimeNode18();
        for (WeatherSubscription weatherSubscription : weatherSubscriptionList) {
            String qqAccount = weatherSubscription.getQqAccount();
            String placeName = weatherSubscription.getPlaceName();
            WeatherLog weatherLog = weatherLogDao.selectWeatherLogByPlaceName(placeName);
            String info = parseToInfo(weatherLog);
            sender.SENDER.sendPrivateMsg(qqAccount,info);

        }
    }

    private String parseToInfo(WeatherLog weatherLog) {
        StringBuilder stringBuilder = new StringBuilder("今天是:" + weatherLog.getDate().toLocalDate()  + "   "  + weatherLog.getWeek()+ "\n");
        stringBuilder.append("[地点]:  " + weatherLog.getArea() + "\n");
        stringBuilder.append("[天气]:  " + weatherLog.getWeather() + "\n");
        stringBuilder.append("[降雨概率]:  " + weatherLog.getPop() + "%" + "\n");
        stringBuilder.append("[降雨量]:  " + weatherLog.getPcpn() + "\n");
        stringBuilder.append("[最低温]:  " + weatherLog.getLowest() + "\n");
        stringBuilder.append("[最高温]:  " + weatherLog.getHighest() + "\n");
        return stringBuilder.toString();
    }

    /**
     * http://api.tianapi.com/txapi/tianqi/index?key=0daf4bf4ee9d40aca3ede135e8f51ffc&city=
     * @param baseUrl http://api.tianapi.com/txapi/tianqi/index
     */
    private void crawling(String baseUrl,String city){
        String requestUrl = baseUrl + "?key=" + constant.getApiKey() + "&city=" + city;
        logger.info("正在爬取的天气地址：" + requestUrl);
        String response = HttpUtils.get(requestUrl).getResponse();
        JSONObject jsonObject = JSONObject.parseObject(response);
        String code = jsonObject.getString("code");
        if("200".equals(code)){
            //请求正确
            List<WeatherLog> weatherLogList = JSONObject.parseArray(jsonObject.getString("newslist"), WeatherLog.class);
            WeatherLog weatherLog = weatherLogList.get(0);
            weatherLogDao.addWeatherLog(Uid.randomUid(),
                    weatherLog.getArea(),
                    weatherLog.getDate(),
                    weatherLog.getWeek(),
                    weatherLog.getWeather(),
                    weatherLog.getRealt(),
                    weatherLog.getLowest(),
                    weatherLog.getHighest(),
                    weatherLog.getWind(),
                    weatherLog.getWinddeg(),
                    weatherLog.getWindspeed(),
                    weatherLog.getWindsc(),
                    weatherLog.getSunrise(),
                    weatherLog.getSunset(),
                    weatherLog.getPcpn(),
                    weatherLog.getUv_index(),
                    weatherLog.getVis(),
                    weatherLog.getHumidity(),
                    weatherLog.getTips(),
                    weatherLog.getPop());
//            for (WeatherLog weatherLog : weatherLogList) {
//                weatherLogDao.addWeatherLog(Uid.randomUid(),
//                        weatherLog.getArea(),
//                        weatherLog.getDate(),
//                        weatherLog.getWeek(),
//                        weatherLog.getWeather(),
//                        weatherLog.getReal(),
//                        weatherLog.getLowest(),
//                        weatherLog.getHighest(),
//                        weatherLog.getWind(),
//                        weatherLog.getWinddeg(),
//                        weatherLog.getWindspeed(),
//                        weatherLog.getWindsc(),
//                        weatherLog.getSunrise(),
//                        weatherLog.getSunset(),
//                        weatherLog.getPcpn(),
//                        weatherLog.getUv_index(),
//                        weatherLog.getVis(),
//                        weatherLog.getHumidity(),
//                        weatherLog.getTips());
//            }

        }

    }

    @Handle(touch = "refresh")
    public void refreshWeather(PrivateMsg privateMsg, Sender sender){
        String baseUrl = "http://api.tianapi.com/txapi/tianqi/index";
        List<WeatherSetting> weatherSettingList = weatherSettingDao.selectAllWeatherSetting();
        for (WeatherSetting weatherSetting : weatherSettingList) {
            String placeName = weatherSetting.getPlaceName();
            crawling(baseUrl,placeName);
        }
        sender.sendPrivateMsg(privateMsg,"刷新完成");
    }


    /*
    *
    * [CAT:rich,content={"app":"com.tencent.map"&#44;"desc":"地图"&#44;"view":"LocationShare"&#44;"ver":"0.0.0.1"&#44;"prompt":"&#91;应用&#93;
    * 地图"&#44;"from":1&#44;"meta":{"Location.Search":{"id":""&#44;"name":"位置分享"&#44;"address":"上海市浦东新区地纬生活广场(荣川路南)"&#44;
    * "lat":"31.194782"&#44;"lng":"121.67595"&#44;"from":"plusPanel"}}&#44;"config":{"forward":1&#44;"autosize":1&#44;"type":"card"}}]
     *
    * */
}
